import { useEffect, useRef } from 'react';
import styles from './index.module.less';
import * as THREE from 'three';
import { OrbitControls } from '../../utils/OrbitControls';
import data from './data';

const entities = data.entities;
const polygons = entities.filter((e: any) => e.type === 'LWPOLYLINE' && e.vertices.length > 2 && e.layer === '摊位图框');

const randomHexColor = () => {	//随机生成十六进制颜色
	return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).substr(-6);
}

const Map = () => {
  const containerRef = useRef(null);
  const sceneRef = useRef<any>(null);
  const cameraRef = useRef<any>(null);
  const rendererRef = useRef<any>(null);
  const zoom = 500;

  const sizes = {
    width: window.innerWidth,
    height: window.innerHeight,
  };

  /**
   * 设置控制器
   * @param camera 
   * @param domElement 
   */
  const initControls = (camera: THREE.PerspectiveCamera, domElement: Document | HTMLCanvasElement | undefined) => {
    const controls = new OrbitControls(camera, domElement);
    controls.target.set(0, 0, 0);
    // 缩放限制
    controls.maxDistance = 100000;
    controls.minDistance = 1;
    // 垂直旋转限制
    controls.minPolarAngle = Math.PI / 2;
    controls.minPolarAngle = Math.PI / 2;
  }

  /**
   * 初始化场景
   * @param canvas 
   */
  const initScene = (canvas: any) => {
    // 初始化场景
    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0xffffff);
    sceneRef.current = scene;
  
    const renderer = new THREE.WebGLRenderer({ canvas });
    rendererRef.current = renderer;
    renderer.setSize(sizes.width, sizes.height);
  }

  /**
   * 初始化相机
   */
  const initCamera = () => {
    // 初始化相机
    const camera = new THREE.PerspectiveCamera(
      30,
      sizes.width / sizes.height,
      0.01,
      20000,
    );
    cameraRef.current = camera;
    camera.position.z = 500;
    camera.lookAt(111110, 100000, 1110);
    camera.position.x = 1000;
    // camera.position.y = -200;

    sceneRef.current.add(camera);
  }

  useEffect(() => {
    initScene(containerRef.current);
    initCamera();
    initControls(cameraRef.current, rendererRef.current.domElement);
    initMap();

    // 动画
    const tick = () => {
      // 更新渲染器
      rendererRef.current.render(sceneRef.current, cameraRef.current);
      // 页面重绘时调用自身
      window.requestAnimationFrame(tick);
    };
    tick();
  }, []);

  const initMap = () => {
    const map = new THREE.Object3D();
    // 遍历形状
    polygons.forEach((geo: any) => {
      // 容器
      const polygon = new THREE.Object3D();

      const shape = new THREE.Shape();
      const linGeometry = new THREE.BufferGeometry();
      const vertices = [];
      for (let i = 0; i < geo.vertices.length; i++) {
        const point = geo.vertices[i];
        if (i === 0) {
          shape.moveTo(point.x / zoom, point.y / zoom);
        }
        shape.lineTo(point.x / zoom, point.y / zoom);
        vertices.push([point.x / zoom, point.y / zoom, 0]);
      }
      const pointArr = new Float32Array(vertices.flat());
      const attrs = new THREE.BufferAttribute( pointArr, 3 );
      linGeometry.setAttribute('position', attrs);

      const extrudeSettings = {
          depth: Math.ceil(Math.random() * 4) + 8,
          bevelEnabled: false
      };
      const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
      // const color = '#d13a34';
      const material = new THREE.MeshBasicMaterial({ color: randomHexColor(), transparent: true, opacity: 1 });
      const mesh = new THREE.Mesh(geometry, material);
      // const line = new THREE.Line(linGeometry, lineMaterial);
      polygon.add(mesh);
      // polygon.add(line)
      map.add(polygon);
    })
    sceneRef.current.add(map);
  };

  const handlerTest = () => {
    console.log(cameraRef.current.position);
  };

  return (
    <div className={styles.container}>
      <canvas className={styles.canvas} ref={containerRef} />
      <div className={styles.operation_container}>
        <div className={styles.operation_btn} onClick={handlerTest}>test</div>
      </div>
    </div>
  );
};

export default Map;